// cm_dbServer.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "ServiceObject.h"
#include "DBEngine_sqlite3.h"
#include <DbgHelp.h>
#pragma comment(lib, "DbgHelp.lib")
using namespace fge;
using namespace ocl;
using namespace protocol;
const char* strDBFile = "..\\bin\\DBServer\\crying-machine.db3";
LONG WINAPI TopLevelFilter( _EXCEPTION_POINTERS *pExceptionInfo );


class CNetMsgListener: public TcpServer::Listener
{
public:
	CNetMsgListener(CMessageManager *pMsgQueue){m_pMsgQueue = pMsgQueue;}
	~CNetMsgListener(void){}
private:
	virtual void	OnAccept( const char* ip, int port, ConnectionID id ){	
		printf("[%d] %s:%d connected\n",id.nID,ip,port);
	}
	virtual void	OnDisconnect( ConnectionID id ){
		printf("%d, disconnected\n",id.nID);
	}
	virtual void	OnSend( const char* body, u_long size, ConnectionID id ){	}
	virtual void	OnRecv( const char* body, u_long size, ConnectionID id ){		
		NetMsg *pMsg = (NetMsg*)body;
		if(pMsg->msg_len <= size)
			m_pMsgQueue->Push(pMsg->msg_id,(BYTE*)pMsg,sizeof(NetMsg),(BYTE*)pMsg+sizeof(NetMsg),size-sizeof(NetMsg));
	}
	virtual void	OnClose( ){	}
private:
	CMessageManager *m_pMsgQueue;
};

int _tmain(int argc, _TCHAR* argv[])
{	
#ifdef _BUFFER_OVERFLLOW	
#if defined(WIN32) && defined(_DEBUG) 
	int tmpDbgFlag;

	tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
	tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
	tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
	_CrtSetDbgFlag(tmpDbgFlag);
#endif //WIN32 & _DEBUG
#endif	
	srand(time(0));
	SetUnhandledExceptionFilter( TopLevelFilter );
	//DBEngine* pDB = new CDBEngine_sqlite3();
	//std::auto_ptr<DBEngine> delEngine(pDB);

	//DBEngine::SelectResult rt;
	//if(!pDB->Open(strDBFile))
	//	return 0;

	//char szSqlBuf[256];
	//sprintf(szSqlBuf,"insert into t_user( name, password, key ) values(\"%s\",\"%s\",%d);",
	//	"aron_d",
	//	"dfffaf",
	//	fge::StrHash("aron_d"));

	//pDB->ExecuteSQL(szSqlBuf);

	//pDB->ExecuteSelect("select * from t_user",rt);
	//for( int r=0; r<rt.rowNum; r++ )
	//{
	//	for( int i=0; i<rt.colNum; i++ )
	//	{
	//		printf("%-10s",rt.data[r][i].c_str());
	//		if( i<(rt.colNum-1))
	//			printf("%-4s","|");
	//		else
	//			printf("\n");
	//	}
	//}
	//getchar();
	CActiveService server;
	server.InstallPlugin( INSTANCE(fge::CTimePlugin) );
	server.Start();

	try
	{
		fge::CXML xmlServer;
		if(!xmlServer.Open("..\\server.xml"))
		{
			char szBuf[256];
			sprintf( szBuf,"can not open file server.xml");
			throw fge::XMLException(szBuf);
		}
		fge::Element* pelement = xmlServer.FindElement("db_server");
		if( !pelement )
		{
			char szBuf[256];
			sprintf( szBuf,"can not open file ", "server.xml");
			throw fge::XMLException("can not find game_server configer in file server.xml");
			throw fge::XMLException(szBuf);
		}

		std::string strIp="127.0.0.1";
		int nPort=9999;

		pelement->GetAttribute("ip",strIp);
		pelement->GetAttribute("port",nPort);

		ocl::TcpServer* pTcpServer	 = INSTANCE(ocl::TcpServer);
		pTcpServer->AddListener(new CNetMsgListener(server.GetMessageQueue()));
		pTcpServer->Open(strIp.c_str(),nPort,0);
	}
	catch (const fge::XMLException& e)
	{
		std::cout<<e.what()<<std::endl;
		fge::CLog::Write(e.what());
		return -1;
	}

	fge::CCmdInterface cmd;
	cmd.SetName("DBServer");
	cmd.Run();

	server.Close();
	return 0;
}

LONG WINAPI TopLevelFilter( _EXCEPTION_POINTERS *pExceptionInfo )
{
	LONG ret = EXCEPTION_CONTINUE_SEARCH;

	time_t  nowtime;
	time(&nowtime);
	struct tm *pTime = localtime(&nowtime);
	char szFile[128] = {0};
	sprintf(szFile, "GameServer_%4d.%02d.%02d_%02d.%02d.%02d.dmp", pTime->tm_year+1900, pTime->tm_mon+1, pTime->tm_mday, pTime->tm_hour, pTime->tm_min, pTime->tm_sec);

	HANDLE hFile = ::CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	if (hFile != INVALID_HANDLE_VALUE)
	{
		MINIDUMP_EXCEPTION_INFORMATION ExInfo;

		ExInfo.ThreadId = ::GetCurrentThreadId();
		ExInfo.ExceptionPointers = pExceptionInfo;
		ExInfo.ClientPointers = NULL;

		// write the dump
		BOOL bOK = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL );
		ret = EXCEPTION_EXECUTE_HANDLER;
		::CloseHandle(hFile);
	}
	return ret;
}
